import threading
import queue
import serial
import asyncio
from serial import SerialException, SerialTimeoutException

class SerialAsync(threading.Thread):
    def __init__(self, port, baudrate=115200):
        super().__init__()
        self._stop_event = threading.Event()
        self._serial = serial.Serial(port=port, baudrate=baudrate)
        self._messages = queue.Queue()
        self._last_message = None
        self.connected = False  # 添加连接状态标志
        self.mutex = threading.Lock()  # 添加互斥锁
        self._received_event = asyncio.Event()  # 添加接收事件

    def run(self):
        try:
            while not self._stop_event.is_set():
                try:
                    line = self._serial.readline()
                    # 假设数据是以行为单位进行传输的，你可以根据具体需求进行数据处理
                    # 此处仅将读取到的行数据放入消息队列中
                    if line:
                        asyncio.run_coroutine_threadsafe(self._handle_message(line.decode().strip()), self._loop)  # 将消息放入队列，并安排处理
                except SerialTimeoutException:
                    pass  
        except SerialException:
            print("串行端口错误，请检查端口是否正确或被占用。")
        finally:
            self._serial.close()

    def _handle_message(self, message):
        while not self._stop_event.is_set():
            if self._messages.empty():
                self._received_event.clear()  # 清除事件，表示没有消息待处理
                break
            else:
                received_message = self._messages.get()
                self._received_event.set()  # 设置事件，表示有消息待处理
                if received_message!= message:   
                    return
                self._last_message = received_message
                break

    async def receive_message(self):
        while not self._stop_event.is_set():
            if self._messages.empty():
                await self._received_event.wait()  # 等待消息到达
            else:
                break

        message = self._messages.get()
        return message             

    def stop(self):
        self._stop_event.set()

    def join(self):
        super().join()

    def get_message(self):
        if not self._messages.empty():
            return self._messages.get()
        return None

    def set_last_message(self, message):
        self._last_message = message


if __name__ == '__main__':
    serial_async = SerialAsync('COM3')  # 将'COM3'替换为你要使用的串行端口
    serial_async.start()

    try:
        while True:
            message = serial_async.receive_message()  # 接收消息
            if message is not None:
                print("Received:", message)

    except KeyboardInterrupt:
        serial_async.stop()
        serial_async.join()
